package com.ec50n9.server.module.user

import com.ec50n9.server.common.render
import com.ec50n9.server.module.common.CreateForm
import com.ec50n9.server.module.common.Render
import com.ec50n9.server.module.common.Rendered
import com.ec50n9.server.module.common.UpdateForm
import com.ec50n9.server.module.role.Role
import org.hibernate.annotations.GenericGenerator
import org.springframework.beans.BeanUtils
import javax.persistence.*
import javax.validation.constraints.NotBlank

@Entity
class User(
    @Column(unique = true)
    var username: String,
    var password: String,
    var nickname: String,
    var salt: String? = null,
    var avatar: String? = null,
    var description: String? = null,
    var status: Int = 1,

    @ManyToMany(fetch = FetchType.EAGER)
    var roles: MutableSet<Role> = mutableSetOf(),

    @Id
    @GenericGenerator(name = "nanoid", strategy = "com.ec50n9.server.common.NanoIdGenerator")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "nanoid")
    var id: String? = null
) : Render<User>()

data class UserQueryRendered(
    var username: String? = null,
    var nickname: String? = null,
    var avatar: String? = null,
    var description: String? = null
) : Rendered<User> {
    override fun renderFrom(from: User) {
        BeanUtils.copyProperties(from, this)
    }
}

/**
 * 创建用户的表单
 */
data class UserCreateForm(

    @field: NotBlank(message = "用户名不能为空")
    var username: String? = null,

    @field: NotBlank(message = "昵称不能为空")
    var nickname: String? = null,

    @field: NotBlank(message = "密码不能为空")
    var password: String? = null,

    var avatar: String? = null,
    var description: String? = null
) : CreateForm<User> {
    override fun renderTo(): User {
        val user = User("", "", "")
        render(user)
        return user
    }
}

/**
 * 全量更新用户表单
 */
data class UserReplaceForm(
    @field: NotBlank(message = "用户名不能为空")
    var username: String? = null,

    @field: NotBlank(message = "昵称不能为空")
    var nickname: String? = null,

    @field: NotBlank(message = "密码不能为空")
    var password: String? = null,

    var avatar: String? = null,
    var description: String? = null
) : UpdateForm<User> {
    override fun renderTo(target: User) {
        renderTo(target)
    }
}

/**
 * 更新用户的表单
 */
data class UserUpdateForm(
    var username: String? = null,
    var nickname: String? = null,
    var password: String? = null,
    var avatar: String? = null,
    var description: String? = null
) : UpdateForm<User> {
    override fun renderTo(target: User) {
        render(target, true)
    }
}
